﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace CFScript
{
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class Variable
    {
        string name;

        string stringValue;
        int intValue;
        bool boolValue;
        decimal decimalValue;
        DateTime datetimeValue;

        VariableType type;

        bool isRuntimeVariable = false;
        bool isDynamicRuntimeVariable = false;

        public bool IsRuntimeVariable
        {
            get
            {
                return this.isRuntimeVariable;
            }
            set
            {
                this.isRuntimeVariable = value;
            }
        }

        public bool IsDynamicRuntimeVariable
        {
            get { return this.isDynamicRuntimeVariable; }
            set { this.isDynamicRuntimeVariable = value; }
        }

        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        public string Value
        {
            get { return this.ToString(); }
            set { this.stringValue = value; }
        }

        public override string ToString()
        {
            string result = this.stringValue;

            switch(this.type)
            {
                case VariableType.IntegerType:
                    result = this.intValue.ToString();
                    break;
                case VariableType.DecimalType:
                    result = this.decimalValue.ToString();
                    break;
                case VariableType.DatetimeType:
                    result = this.datetimeValue.ToString("dd/MM/yyyy hh:mm:ss");
                    break;
                case VariableType.BoolType:
                    result = this.boolValue.ToString();
                    break;
            }

            return result;
        }

        public int ValueAsInt
        {
            get { return this.intValue; }
            set { this.intValue = value; }
        }

        public decimal ValueAsDecimal
        {
            get { return this.decimalValue; }
            set { this.decimalValue = value; }
        }

        public bool ValueAsBool
        {
            get { return this.boolValue; }
            set { this.boolValue = value; }
        }

        public DateTime ValueAsDateTime
        {
            get { return this.datetimeValue; }
            set { this.datetimeValue = value; }
        }

        public VariableType Type
        {
            get { return this.type; }
            set { this.type = value; }
        }

        public Variable(string name) : this(name, "") { }

        public Variable(string name, string value)
        {
            this.name = name;
            this.stringValue = value;
            this.type = VariableType.StringType;
        }

        public Variable(string name, int value):this(name,value.ToString())
        {
            this.intValue = value;
            this.type = VariableType.IntegerType;
        }

        public Variable(string name, decimal value):this(name, value.ToString())
        {
            this.decimalValue = value;
            this.type = VariableType.DecimalType;
        }

        public Variable(string name, bool value):this(name, value.ToString())
        {
            this.boolValue = value;
            this.type = VariableType.BoolType;
        }

        public Variable(string name, DateTime value):this(name,value.ToString("dd/MM/yyyy hh:mm:ss"))
        {
            this.datetimeValue = value;
            this.type = VariableType.DatetimeType;
        }

        public static Variable RuntimeVariableFactory(string name, string value, string type)
        {
            Variable instance = VariableFactory(name, value, type);
            if (instance != null)
            {
                instance.isRuntimeVariable = true;
            }

            return instance;
        }

        public static Variable VariableFactory(string name, string value, string type)
        {
            Variable instance = null;
            VariableType vt = VariableType.StringType;

            if (type != null)
            {
                vt = (VariableType)Enum.Parse(typeof(VariableType), type + "Type", true);
            }
            value = value != null ? value : "";

            switch(vt)
            {
                case VariableType.StringType:
                    instance = new Variable(name, value);
                    break;
                case VariableType.IntegerType:
                    value = value != "" ? value : "0";
                    instance = new Variable(name, int.Parse(value));
                    break;
                case VariableType.DecimalType:
                    value = value != "" ? value : "0.0";
                    instance = new Variable(name, decimal.Parse(value));
                    break;
                case VariableType.DatetimeType:
                    value = value != "" ? value : "1970/01/01 00:00:00";
                    instance = new Variable(name, DateTime.ParseExact(value,"yyyy/MM/dd HH:mm:ss",CultureInfo.InvariantCulture));
                    break;
                case VariableType.BoolType:
                    value = value != "" ? value : "false";
                    instance = new Variable(name, bool.Parse(value));
                    break;
            }

            return instance;
        }
    }

    public enum VariableType
    {
        IntegerType,
        DecimalType,
        StringType,
        DatetimeType,
        BoolType
    }
}
